package varconvert

import (
	"fmt"
	"strconv"
)

func ConvertDataTypeBasic() {
	fmt.Println("in func ConvertDataTypeBasic")
	//基本的数据类型转换
	a := int(3.0)
	fmt.Println(a)
	//go 语言不支持变量间的隐性类型转换：b 是int ,c是float， b=c是不行的
	// 1.变量间隐性类型转换不行
	fmt.Print("a: ")
	fmt.Printf("%T\n", 5.0)
	var b int = 5.0 //这里可以，因为5.0是常量
	//var b int = 5.1 //这里隐式也是不可以，所以即使做隐性类型转化，要求也很严格
	fmt.Println("b: ", b)

	var c float64 = 5.0
	fmt.Print("c: ")
	fmt.Printf("%T \n", c)

	// b =c 是不行的
	//b = c

	// int和string之间不能做强制类型转换
	//var e int = int("1") //错误的

	g := 6.1
	var h int = int(g) //声明的时候可以这样做强制类型转化
	//h = int(8.3) //这样不行
	fmt.Println("h: ", h)
}

func ConvertDataTypeSimple() {

	fmt.Println("in func ConvertDataTypeSimple")

	{
		// 浮点数
		a := 5.0

		// 转换为int类型
		b := int(a)

		fmt.Println(b)
	}

	//Go允许在底层结构相同的两个类型之间互转。例如：
	// IT类型的底层是int类型
	type IT int

	// a的类型为IT，底层是int
	var a IT = 5

	// 将a(IT)转换为int，b现在是int类型
	b := int(a)

	// 将b(int)转换为IT，c现在是IT类型
	c := IT(b)

	fmt.Println("c: ", c)

	var g int32 = 1
	var h int64 = 3
	h = int64(g)
	fmt.Println(g, h)

	/*
	   不是所有数据类型都能转换的，例如字母格式的string类型"abcd"转换为int肯定会失败
	   低精度转换为高精度时是安全的，高精度的值转换为低精度时会丢失精度。例如int32转换为int16，float32转换为int
	   这种简单的转换方式不能对int(float)和string进行互转，要跨大类型转换，可以使用strconv包提供的函数
	*/
}

func ConvertDataTypeByStrconv() {

	fmt.Println("test strconv: ")

	//int to string
	fmt.Println("Itoa: ")
	var a int64 = 56
	fmt.Printf("%T \n", strconv.Itoa(int(a)))

	//string to int
	fmt.Println("Atoi: ")
	data, err := strconv.Atoi("12")
	if err != nil {
		fmt.Println("Error: ", err)
	}
	fmt.Println(data)

	fmt.Println(".....Parse类函数: str to others ....")
	b, err := strconv.ParseBool("true")
	fmt.Println("ParseBool: ", b)
	c, err := strconv.ParseBool("q")
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println(c)
	}

	fmt.Println("ParseFloat: ")
	f, _ := strconv.ParseFloat("3.1415", 32)
	fmt.Printf("%T \n", f)
	fmt.Println(f)

	fmt.Println("ParseInt and ParseUint")
	i, _ := strconv.ParseInt("-42", 10, 64)
	fmt.Println(i)
	u, _ := strconv.ParseUint("42", 10, 64)
	fmt.Println(u)

	fmt.Println("...Format类函数 others to str...")
	s1 := strconv.FormatBool(true)
	s2 := strconv.FormatFloat(3.1415, 'E', -1, 64)
	s3 := strconv.FormatInt(-42, 16) //表示将-42转换为16进制数，转换的结果为-2a。
	s4 := strconv.FormatUint(42, 16)
	fmt.Println(s1, s2, s3, s4)
}
